/* iui.Extension
 * @author Adam Freidin 
 * @coded_at SHDH 44
 */
iui.Extension = function(name, handlers) {
  var selector;
  var event_handlers = {};
  var default_adapter = iui.Extension.adapters._;
  for(var key in handlers) switch(key) {
  case "selector": 
    selector = handlers.selector;
    break;
  default:
    event_handlers[key] = new function(adapter, handler) { 
      return function(e) {
        // this is a great place to try-catch 
        // and log plugin::handler exceptions.
        return adapter.call(this, handler, e);
      };
    }(iui.Extension.adapters[key] || default_adapter, handlers[key]);
  }
  
  addEventListener("DOMContentLoaded", function() {
    document.body.addEventListener('afterinsert', function(e) {
      register(e.insertedNode);
      if(event_handlers.afterinsert) event_handlers.afterinsert.call(this, e);
    }, false);

    var nodes;

    if(selector) switch(typeof selector) {
    case 'function': nodes = selector.call(iui); break;
    case 'string': nodes = document.querySelectorAll(selector); break;
    default: 
      if(selector) { throw "Bad Extension Selector"; }
      nodes = iui.getAllViews();
    }

    for (var i = 0; i  < nodes.length  ; i++) {
      register(nodes[i]);
    }
  }, false);

  function register(node) {
    for(var event_type in event_handlers) {
      node.addEventListener(event_type, event_handlers[event_type]);
    }
  }
};

iui.Extension.adapters = {
  afterinsert: function(fn, e) {
    return fn.call(e.insertedNode, e);
  },
  beforeinsert: function(fn, e) {
    return fn.call(e.fragment, e);
  },
  afterinsert: function(fn, e) {
    return fn.call(e.insertedNode, e);
  },
  afterinsertend: function(fn, e) {
    return fn.call(e.fragment, e);
  },
  _: function(fn, e) {
    return fn.call(e.target, e);
  }
};
